
/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2021原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.core.annotation.AliasFor;

/**
 * Indicates that a method produces a bean to be managed by the Spring container.
 *
 * <h3>Overview</h3>
 *
 * <p>The names and semantics of the attributes to this annotation are intentionally
 * similar to those of the {@code <bean/>} element in the Spring XML schema. For
 * example:
 *
 * <pre class="code">
 *     &#064;Bean
 *     public MyBean myBean() {
 *         // instantiate and configure MyBean obj
 *         return obj;
 *     }
 * </pre>
 *
 * <h3>Bean Names</h3>
 *
 * <p>While a {@link #name} attribute is available, the default strategy for
 * determining the name of a bean is to use the name of the {@code @Bean} method.
 * This is convenient and intuitive, but if explicit naming is desired, the
 * {@code name} attribute (or its alias {@code value}) may be used. Also note
 * that {@code name} accepts an array of Strings, allowing for multiple names
 * (i.e. a primary bean name plus one or more aliases) for a single bean.
 *
 * <pre class="code">
 *     &#064;Bean({"b1", "b2"}) // bean available as 'b1' and 'b2', but not 'myBean'
 *     public MyBean myBean() {
 *         // instantiate and configure MyBean obj
 *         return obj;
 *     }
 * </pre>
 *
 * <h3>Profile, Scope, Lazy, DependsOn, Primary, Order</h3>
 *
 * <p>Note that the {@code @Bean} annotation does not provide attributes for profile,
 * scope, lazy, depends-on or primary. Rather, it should be used in conjunction with
 * {@link Scope @Scope}, {@link Lazy @Lazy}, {@link DependsOn @DependsOn} and
 * {@link Primary @Primary} annotations to declare those semantics. For example:
 *
 * <pre class="code">
 *     &#064;Bean
 *     &#064;Profile("production")
 *     &#064;Scope("prototype")
 *     public MyBean myBean() {
 *         // instantiate and configure MyBean obj
 *         return obj;
 *     }
 * </pre>
 *
 * The semantics of the above-mentioned annotations match their use at the component
 * class level: {@code @Profile} allows for selective inclusion of certain beans.
 * {@code @Scope} changes the bean's scope from singleton to the specified scope.
 * {@code @Lazy} only has an actual effect in case of the default singleton scope.
 * {@code @DependsOn} enforces the creation of specific other beans before this
 * bean will be created, in addition to any dependencies that the bean expressed
 * through direct references, which is typically helpful for singleton startup.
 * {@code @Primary} is a mechanism to resolve ambiguity at the injection point level
 * if a single target component needs to be injected but several beans match by type.
 *
 * <p>Additionally, {@code @Bean} methods may also declare qualifier annotations
 * and {@link org.springframework.core.annotation.Order @Order} values, to be
 * taken into account during injection point resolution just like corresponding
 * annotations on the corresponding component classes but potentially being very
 * individual per bean definition (in case of multiple definitions with the same
 * bean class). Qualifiers narrow the set of candidates after the initial type match;
 * order values determine the order of resolved elements in case of collection
 * injection points (with several target beans matching by type and qualifier).
 *
 * <p><b>NOTE:</b> {@code @Order} values may influence priorities at injection points,
 * but please be aware that they do not influence singleton startup order which is an
 * orthogonal concern determined by dependency relationships and {@code @DependsOn}
 * declarations as mentioned above. Also, {@link jakarta.annotation.Priority} is not
 * available at this level since it cannot be declared on methods; its semantics can
 * be modeled through {@code @Order} values in combination with {@code @Primary} on
 * a single bean per type.
 *
 * <h3>{@code @Bean} Methods in {@code @Configuration} Classes</h3>
 *
 * <p>Typically, {@code @Bean} methods are declared within {@code @Configuration}
 * classes. In this case, bean methods may reference other {@code @Bean} methods in the
 * same class by calling them <i>directly</i>. This ensures that references between beans
 * are strongly typed and navigable. Such so-called <em>'inter-bean references'</em> are
 * guaranteed to respect scoping and AOP semantics, just like {@code getBean()} lookups
 * would. These are the semantics known from the original 'Spring JavaConfig' project
 * which require CGLIB subclassing of each such configuration class at runtime. As a
 * consequence, {@code @Configuration} classes and their factory methods must not be
 * marked as final or private in this mode. For example:
 *
 * <pre class="code">
 * &#064;Configuration
 * public class AppConfig {
 *
 *     &#064;Bean
 *     public FooService fooService() {
 *         return new FooService(fooRepository());
 *     }
 *
 *     &#064;Bean
 *     public FooRepository fooRepository() {
 *         return new JdbcFooRepository(dataSource());
 *     }
 *
 *     // ...
 * }</pre>
 *
 * <h3>{@code @Bean} <em>Lite</em> Mode</h3>
 *
 * <p>{@code @Bean} methods may also be declared within classes that are <em>not</em>
 * annotated with {@code @Configuration}. For example, bean methods may be declared
 * in a {@code @Component} class or even in a <em>plain old class</em>. In such cases,
 * a {@code @Bean} method will get processed in a so-called <em>'lite'</em> mode.
 *
 * <p>Bean methods in <em>lite</em> mode will be treated as plain <em>factory
 * methods</em> by the container (similar to {@code factory-method} declarations
 * in XML), with scoping and lifecycle callbacks properly applied. The containing
 * class remains unmodified in this case, and there are no unusual constraints for
 * the containing class or the factory methods.
 *
 * <p>In contrast to the semantics for bean methods in {@code @Configuration} classes,
 * <em>'inter-bean references'</em> are not supported in <em>lite</em> mode. Instead,
 * when one {@code @Bean}-method invokes another {@code @Bean}-method in <em>lite</em>
 * mode, the invocation is a standard Java method invocation; Spring does not intercept
 * the invocation via a CGLIB proxy. This is analogous to inter-{@code @Transactional}
 * method calls where in proxy mode, Spring does not intercept the invocation &mdash;
 * Spring does so only in AspectJ mode.
 *
 * <p>For example:
 *
 * <pre class="code">
 * &#064;Component
 * public class Calculator {
 *     public int sum(int a, int b) {
 *         return a+b;
 *     }
 *
 *     &#064;Bean
 *     public MyBean myBean() {
 *         return new MyBean();
 *     }
 * }</pre>
 *
 * <h3>Bootstrapping</h3>
 *
 * <p>See the @{@link Configuration} javadoc for further details including how to bootstrap
 * the container using {@link AnnotationConfigApplicationContext} and friends.
 *
 * <h3>{@code BeanFactoryPostProcessor}-returning {@code @Bean} methods</h3>
 *
 * <p>Special consideration must be taken for {@code @Bean} methods that return Spring
 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessor}
 * ({@code BFPP}) types. Because {@code BFPP} objects must be instantiated very early in the
 * container lifecycle, they can interfere with processing of annotations such as {@code @Autowired},
 * {@code @Value}, and {@code @PostConstruct} within {@code @Configuration} classes. To avoid these
 * lifecycle issues, mark {@code BFPP}-returning {@code @Bean} methods as {@code static}. For example:
 *
 * <pre class="code">
 *     &#064;Bean
 *     public static PropertySourcesPlaceholderConfigurer pspc() {
 *         // instantiate, configure and return pspc ...
 *     }
 * </pre>
 *
 * By marking this method as {@code static}, it can be invoked without causing instantiation of its
 * declaring {@code @Configuration} class, thus avoiding the above-mentioned lifecycle conflicts.
 * Note however that {@code static} {@code @Bean} methods will not be enhanced for scoping and AOP
 * semantics as mentioned above. This works out in {@code BFPP} cases, as they are not typically
 * referenced by other {@code @Bean} methods. As a reminder, an INFO-level log message will be
 * issued for any non-static {@code @Bean} methods having a return type assignable to
 * {@code BeanFactoryPostProcessor}.
 *
 * @author Rod Johnson
 * @author Costin Leau
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 * @see Configuration
 * @see Scope
 * @see DependsOn
 * @see Lazy
 * @see Primary
 * @see org.springframework.stereotype.Component
 * @see org.springframework.beans.factory.annotation.Autowired
 * @see org.springframework.beans.factory.annotation.Value
 */
/**
 *指示一个方法生成一个由Spring容器管理的bean。
 *
 *<h3>概述</h3>
 *
 *<p>此注释的属性的名称和语义是有意的
 *类似于Spring XML模式中的{@code＜bean/＞}元素。对于
 *示例：
 *
 *<pre-class=“code”>
 *     &#064;豆
 *公共MyBean MyBean（）{
 *//实例化并配置MyBean obj
 *返回obj；
 *     }
 *</pre>
 *
 *<h3>Bean名称</h3>
 *
 *＜p＞当｛@link#name｝属性可用时
 *确定bean的名称是使用{@code@bean}方法的名称。
 *这既方便又直观，但如果需要显式命名
 *可以使用{@code-name}属性（或其别名{@code-value}）。另请注意
 *｛@code name｝接受字符串数组，允许使用多个名称
 *（即一个主bean名称加上一个或多个别名）。
 *
 *<pre-class=“code”>
 *     &#064;Bean（｛“b1”，“b2”｝）//可用作“b1”和“b2”，但不可用作“myBean”
 *公共MyBean MyBean（）{
 *//实例化并配置MyBean obj
 *返回obj；
 *     }
 *</pre>
 *
 *<h3>配置文件、作用域、延迟、依赖项打开、主要、顺序</h3>
 *
 *<p>请注意，{@code@Bean}注释不提供profile的属性，
 *scope、lazy、dependent或primary。相反，它应该与
 *｛@link Scope@Scope｝、｛@link-Lazay@Lazy｝、{@link-DependensOn@DependensOn｝和
 *｛@link Primary@Primary｝注释来声明这些语义。例如：
 *
 *<pre-class=“code”>
 *     &#064;豆
 *     &#064;简介（“生产”）
 *     &#064;范围（“原型”）
 *公共MyBean MyBean（）{
 *//实例化并配置MyBean obj
 *返回obj；
 *     }
 *</pre>
 *
 *上述注释的语义与其在组件中的使用相匹配
 *类级别：｛@code@Profile｝允许选择性地包含某些bean。
 *｛@code@Scope｝将bean的作用域从singleton更改为指定的作用域。
 *｛@code@Lazy｝只有在默认的单例作用域的情况下才有实际效果。
 *｛@code@DependsOn｝在此之前强制创建特定的其他bean
 *除了bean所表达的任何依赖项之外，还将创建bean
 *通过直接引用，这通常有助于单例启动。
 *｛@code@Primary｝是一种在注入点级别解决歧义的机制
 *如果需要注入单个目标组件，但几个bean按类型匹配。
 *
 *＜p＞此外，｛@code@Bean｝方法也可以声明限定符注释
 *和{@link org.springframework.core.annotation.Order@Order}值
 *在注入点解析过程中考虑，就像对应的一样
 *相应组件类上的注释，但可能非常
 *每个bean的单个定义（在多个定义具有相同定义的情况下
 *bean类）。限定符在初始类型匹配之后缩小候选集；
 *顺序值决定集合情况下已解析元素的顺序
 *注入点（具有按类型和限定符匹配的几个目标bean）。
 *
 *<p><b>注意：</b>{@code@Order}值可能会影响注入点的优先级，
 *但请注意，它们不会影响单例启动顺序，这是一个
 *由依赖关系和{@code@DependsOn}确定的正交关注点
 *上述声明。此外，｛@link jakarta.annotation.Priority｝不是
 *在该级别可用，因为它不能在方法上声明；它的语义可以
 *通过上的｛@code@Order｝值与｛@code@Primary｝组合进行建模
 *每种类型一颗豆子。
 *
 *<h3>｛@code@Bean｝类中的方法</h3>
 *
 *＜p＞通常，｛@code@Bean｝方法是在｛@code@Configuration｝中声明的
 *类。在这种情况下，bean方法可以引用
 *通过直接调用它们<i></i>来实现相同的类。这确保了bean之间的引用
 *是强类型的和可导航的。这种所谓的<em>“跨代引用”</em>是
 *保证尊重作用域和AOP语义，就像{@code getBean（）}查找一样
 *会的。这些是从最初的“Spring JavaConfig”项目中已知的语义
 *其需要在运行时对每个这样的配置类进行CGLIB子类化。作为一个
 *因此，｛@code@Configuration｝类及其工厂方法不能
 *在此模式下标记为最终或私有。例如：
 *
 *<pre-class=“code”>
 * &#064;配置
 *公共类AppConfig{
 *
 *     &#064;豆
 *公共FooService FooService（）{
 *返回新的FooService（fooRepository（））；
 *     }
 *
 *     &#064;豆
 *公共FooRepository FooRepository（）{
 *返回新的JdbcFooRepository（dataSource（））；
 *     }
 *
 *     // ...
 *}</pre>
 *
 *<h3>｛@code@Bean｝<em>精简版</em>模式</h3>
 *
 *＜p＞｛@code@Bean｝方法也可以在不是＜em＞的类中声明</em>
 *用｛@code@Configuration｝注释。例如，可以声明bean方法
 *在{@code@Component}类中，甚至在<em>普通旧类</em>中。在这种情况下，
 *{@code@Bean}方法将以所谓的<em>“站点”</em>模式进行处理。
 *
 *<p><em>lite</em>模式中的Bean方法将被视为普通<em>工厂
 *容器的方法</em>（类似于{@code factory method}声明
 *在XML中），并正确应用范围界定和生命周期回调。包含
 *在这种情况下，类保持不变，并且对
 *包含类或工厂方法。
 *
 *<p>与{@code@Configuration}类中bean方法的语义相反，
 *<em>精简版</em>模式不支持<em>“跨代引用”</em>。相反
 *当一个{@code@Bean}-方法调用<em>lite中的另一个{:code@Bean}-方法时</em>
 *模式下，调用是标准的Java方法调用；弹簧不拦截
 *通过CGLIB代理的调用。这类似于inter-{@code@Transactional}
 *方法调用，其中在代理模式下，Spring不拦截调用&mdash；
 *Spring只在AspectJ模式下执行此操作。
 *
 *<p>例如：
 *
 *<pre-class=“code”>
 * &#064;组成部分
 *公共类计算器{
 *公共整数和（int a，int b）{
 *返回a+b；
 *     }
 *
 *     &#064;豆
 *公共MyBean MyBean（）{
 *返回新的MyBean（）；
 *     }
 *}</pre>
 *
 *<h3>引导</h3>
 *
 *＜p＞请参阅@｛@link Configuration｝javadoc以了解更多详细信息，包括如何引导
 *使用｛@link AnnotationConfigApplicationContext｝和朋友的容器。
 *
 *<h3>｛@code BeanFactoryPostProcessor｝-返回｛@code@Bean｝方法</h3>
 *
 *＜p＞必须特别考虑返回Spring的｛@code@Bean｝方法
 *｛@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcesser｝
 *（{@code-BFPP}）类型。因为｛@code BFPP｝对象必须在
 *容器生命周期中，它们可能会干扰注释的处理，例如{@code@Autowired}，
 *｛@code@Value｝和｛@code@PostConstruct｝中的类。为了避免这些
 *生命周期问题，将{@code-BFPP}-返回的{@code@Bean}方法标记为{@code-static}。例如：
 *
 *<pre-class=“code”>
 *     &#064;豆
 *公共静态PropertySourcesPlaceholderConfigurer pspc（）{
 *//实例化、配置并返回pspc。。。
 *     }
 *</pre>
 *
 *通过将此方法标记为{@code-static}，可以在不引起其实例化的情况下调用它
 *声明{@code@Configuration}类，从而避免了上述生命周期冲突。
 *但是请注意，｛@code static｝｛@code@Bean｝方法将不会针对作用域和AOP进行增强
 *如上所述的语义。这在{@code-BFPP}的情况下是可行的，因为它们通常不是
 *被其他{@code@Bean}方法引用。作为提醒，将显示INFO级别的日志消息
 *为具有可分配给的返回类型的任何非静态｛@code@Bean｝方法发出
 *｛@code BeanFactoryPostProcessor｝。
 *
 *@作者罗德·约翰逊
 *@作者Costin Leau
 *@作者Chris Beams
 *@作者Juergen Hoeller
 *@作者Sam Brannen
 *@自3.0起
 *@请参阅配置
 *@见范围
 *@请参阅DependsOn
 *@见懒惰
 *@见初级
 *@参见org.springframework.stereotype.Component
 *@参见org.springframework.beans.factory.annotation.Autowired
 *@参见org.springframework.beans.factory.annotation.Value
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

	/**
	 * Alias for {@link #name}.
	 * <p>Intended to be used when no other attributes are needed, for example:
	 * {@code @Bean("customBeanName")}.
	 * @since 4.3.3
	 * @see #name
	 */
	/**
	 *｛@link#name｝的别名。
	 *<p>适用于不需要其他属性的情况，例如：
	 *{@code@Bean（“customBeanName”）}。
	 *@自4.3.3起
	 *@参见#名称
	 */
	@AliasFor("name")
	String[] value() default {};

	/**
	 * The name of this bean, or if several names, a primary bean name plus aliases.
	 * <p>If left unspecified, the name of the bean is the name of the annotated method.
	 * If specified, the method name is ignored.
	 * <p>The bean name and aliases may also be configured via the {@link #value}
	 * attribute if no other attributes are declared.
	 * @see #value
	 */
	/**
	 *这个bean的名称，或者如果有几个名称，则是一个主bean名称加上别名。
	 *＜p＞如果未指定，那么bean的名称就是带注释的方法的名称。
	 *如果指定，则会忽略方法名称。
	 *＜p＞bean名称和别名也可以通过｛@link#值｝进行配置
	 *属性（如果未声明其他属性）。
	 *@见#值
	 */
	@AliasFor("value")
	String[] name() default {};

	/**
	 * Is this bean a candidate for getting autowired into some other bean?
	 * <p>Default is {@code true}; set this to {@code false} for internal delegates
	 * that are not meant to get in the way of beans of the same type in other places.
	 * @since 5.1
	 */
	/**
	 *这个bean是自动连接到其他bean的候选者吗？
	 *＜p＞默认值为｛@code true｝；对于内部委托，将其设置为｛@code false｝
	 *这并不意味着妨碍其他地方的同类豆类。
	 *@自5.1起
	 */
	boolean autowireCandidate() default true;

	/**
	 * The optional name of a method to call on the bean instance during initialization.
	 * Not commonly used, given that the method may be called programmatically directly
	 * within the body of a Bean-annotated method.
	 * <p>The default value is {@code ""}, indicating no init method to be called.
	 * @see org.springframework.beans.factory.InitializingBean
	 * @see org.springframework.context.ConfigurableApplicationContext#refresh()
	 */
	/**
	 *在初始化期间要在bean实例上调用的方法的可选名称。
	 *不常用，因为该方法可以通过编程直接调用
	 *在Bean注释方法的主体中。
	 *<p>默认值为{@code“”}，表示没有要调用的init方法。
	 *@参见org.springframework.beans.factory.InitializingBean
	 *请参阅org.springframework.context.ConfiguratableApplicationContext#refresh（）
	 */
	String initMethod() default "";

	/**
	 * The optional name of a method to call on the bean instance upon closing the
	 * application context, for example a {@code close()} method on a JDBC
	 * {@code DataSource} implementation, or a Hibernate {@code SessionFactory} object.
	 * The method must have no arguments but may throw any exception.
	 * <p>As a convenience to the user, the container will attempt to infer a destroy
	 * method against an object returned from the {@code @Bean} method. For example, given
	 * an {@code @Bean} method returning an Apache Commons DBCP {@code BasicDataSource},
	 * the container will notice the {@code close()} method available on that object and
	 * automatically register it as the {@code destroyMethod}. This 'destroy method
	 * inference' is currently limited to detecting only public, no-arg methods named
	 * 'close' or 'shutdown'. The method may be declared at any level of the inheritance
	 * hierarchy and will be detected regardless of the return type of the {@code @Bean}
	 * method (i.e., detection occurs reflectively against the bean instance itself at
	 * creation time).
	 * <p>To disable destroy method inference for a particular {@code @Bean}, specify an
	 * empty string as the value, e.g. {@code @Bean(destroyMethod="")}. Note that the
	 * {@link org.springframework.beans.factory.DisposableBean} callback interface will
	 * nevertheless get detected and the corresponding destroy method invoked: In other
	 * words, {@code destroyMethod=""} only affects custom close/shutdown methods and
	 * {@link java.io.Closeable}/{@link java.lang.AutoCloseable} declared close methods.
	 * <p>Note: Only invoked on beans whose lifecycle is under the full control of the
	 * factory, which is always the case for singletons but not guaranteed for any
	 * other scope.
	 * @see org.springframework.beans.factory.DisposableBean
	 * @see org.springframework.context.ConfigurableApplicationContext#close()
	 */
	/**
	 *在关闭时要调用bean实例的方法的可选名称
	 *应用程序上下文，例如JDBC上的{@code close（）}方法
	 *｛@code DataSource｝实现，或Hibernate｛@code-SessionFactory｝对象。
	 *该方法不能有任何参数，但可能引发任何异常。
	 *＜p＞为了方便用户，容器将尝试推断销毁
	 *方法对从｛@code@Bean｝方法返回的对象执行。例如，给定
	 *返回Apache Commons DBCP的{@code@Bean}方法{@code-BasicDataSource}，
	 *容器将注意到该对象上可用的{@code close（）}方法，并且
	 *自动将其注册为｛@code destroyMethod｝。这种“销毁方法”
	 *“推理”目前仅限于检测公共的，没有名为的arg方法
	 *“关闭”或“关闭”。该方法可以在继承的任何级别上声明
	 *层次结构，并且无论{@code@Bean}的返回类型如何都将被检测到
	 *方法（即，在
	 *创建时间）。
	 *＜p＞若要禁用特定｛@code@Bean｝的destroy方法推理，请指定
	 *空字符串作为值，例如{@code@Bean（destroyMethod=“”）}。请注意
	 *｛@link org.springframework.beans.factory.DisposableBean｝回调接口将
	 *尽管如此，还是被检测到并调用了相应的destroy方法：在其他
	 *words，｛@code destroyMethod=“”｝仅影响自定义关闭/关闭方法和
	 *｛@link java.io.Closeable｝/｛@linkjava.lang.AutoCloseable｝声明了关闭方法。
	 *＜p＞注意：仅在其生命周期完全受
	 *工厂，单身人士总是这样，但任何人都不能保证
	 *其他范围。
	 *@参见org.springframework.beans.factory.DisposableBean
	 *请参阅org.springframework.context.ConfiguratableApplicationContext#close（）
	 */
	String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}
